package com.webchat.chat;

import com.corundumstudio.socketio.AuthorizationListener;
import com.corundumstudio.socketio.HandshakeData;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import com.webchat.chat.core.enums.SocketClientType;
import com.webchat.chat.core.exception.MessageExceptionListener;
import com.webchat.chat.core.redis.RedisService;
import com.webchat.chat.core.tools.RedisConstant;
import com.webchat.chat.core.tools.SocketConstant;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.Objects;

/**
 * Created by Owner on 2018/6/26.
 */
@SpringBootApplication
@EnableCaching //开启缓存
@EnableTransactionManagement// 开启事务管理
@EnableScheduling //定时任务
@MapperScan(value = "com.webchat.chat.dao")
public class Application {

    @Value("${wss.server.host}")
    private String host;

    @Value("${wss.server.port}")
    private Integer port;

    @Resource
    private RedisService redisService;

    private SocketIOServer server;

    @Bean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setHostname(host);
        config.setPort(port);
        config.setTransports(Transport.POLLING, Transport.WEBSOCKET);
        config.setExceptionListener(new MessageExceptionListener());

        //身份验证
        config.setAuthorizationListener(new AuthorizationListener() {
            @Override
            public boolean isAuthorized(HandshakeData data) {
                String sct = data.getSingleUrlParam(SocketConstant.SOCKET_CLIENT_TYPE);
                String tc = data.getSingleUrlParam(SocketConstant.TENANT_CODE);

                if (StringUtils.isBlank(sct) || StringUtils.isBlank(tc)) { return false;  }

                SocketClientType socketClientType = SocketClientType.valueOf(sct);

                if (Objects.equals(socketClientType, SocketClientType.客服)) {
                    String id = data.getSingleUrlParam(SocketConstant.CONNECT_ID);
                    String pd = data.getSingleUrlParam(SocketConstant.PWD_CONNECT);

                    if (StringUtils.isBlank(id) || StringUtils.isBlank(pd)) {   return false;   }

                    String pwdConnect = (String) redisService.getMapField(RedisConstant.PWD_CONNECT, id);

                    if (StringUtils.isBlank(pwdConnect) || !Objects.equals(pd, pwdConnect)) {  return false;  }

                }
                return true;
            }
        });

        config.getSocketConfig().setReuseAddress(true);
        config.getSocketConfig().setSoLinger(0);
        config.getSocketConfig().setTcpNoDelay(true);
        config.getSocketConfig().setTcpKeepAlive(true);

        return server = new SocketIOServer(config);
    }

    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }

    @PreDestroy
    public void destory() {
        server.stop();
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
